export const EOF = Symbol('EOF');
export type StateFn = (c: string | typeof EOF) => StateFn | void;

export abstract class Parser {
  public isFinished: boolean = false;

  protected abstract state: StateFn;

  parse(string: string) {
    for (let i = 0; i < string.length; i++) {
      this.consume(string.charAt(i));
    }

    this.consume(EOF);
    this.isFinished = true;
  }

  consume(char: string | typeof EOF) {
    const newState = this.state(char);

    if (newState == null) {
      throw new Error('Unexpected token: ' + char.toString());
    }

    this.state = newState;
  }
}
